﻿using System;
using System.Collections.Generic;
using System.Drawing;

namespace InvariantWM
{
    class WatermarkProcessor
    {
        public static Bitmap insertWatermark(Bitmap image, string clave)
        {
            Bitmap watermarkedImage = new Bitmap(image.Width, image.Height);
            
            //Create auxiliary matrices
            double[,] wmRed = new double[image.Height, image.Width];
            double[,] wmGreen = new double[image.Height, image.Width];
            double[,] wmBlue = new double[image.Height, image.Width];
            double[,] wmAlpha = new double[image.Height, image.Width];

            //Load them with the source color info
            for (int i = 0; i < image.Height; i++)
            {
                for (int j = 0; j < image.Width; j++)
                {
                    Color auxColor = image.GetPixel(j, i);
                    wmRed[i, j] = auxColor.R;
                    wmGreen[i, j] = auxColor.G;
                    wmBlue[i, j] = auxColor.B;
                    wmAlpha[i, j] = auxColor.A;             
                }
            }

            //Convert the key to a long type. (It's simple hasing)
            long keyAcu = 0;            
            foreach (char c in clave)
            {
                keyAcu += c;
            }

            //Make the dct direct transform
            wmRed = DCT.directTransform(wmRed);
            wmGreen = DCT.directTransform(wmGreen);
            wmBlue = DCT.directTransform(wmBlue);
            wmAlpha = DCT.directTransform(wmAlpha);

            //Insert the watermark
            Watermarker wmMarker = new Watermarker(clave);
           
            wmRed = wmMarker.InsertWatermark(wmRed);
            wmBlue = wmMarker.InsertWatermark(wmBlue);
            wmGreen = wmMarker.InsertWatermark(wmGreen);
            wmAlpha = wmMarker.InsertWatermark(wmAlpha);

            //Inverse dct transform
            wmRed = DCT.inverseTransform(wmRed);
            wmGreen = DCT.inverseTransform(wmGreen);
            wmBlue = DCT.inverseTransform(wmBlue);
            wmAlpha = DCT.inverseTransform(wmAlpha);

            //Store the new color info in watermakedImage
            for (int i = 0; i < image.Height; i++)
            {
                for (int j = 0; j < image.Width; j++)
                {
                    int r = validador((int)Math.Round(wmRed[i, j]));
                    //int r = (int)Math.Round(wmRed[i, j]);
                    int g = validador((int)Math.Round(wmGreen[i, j]));
                    //int g = (int)Math.Round(wmGreen[i, j]);
                    int b = validador((int)Math.Round(wmBlue[i, j]));
                    //int b = (int)Math.Round(wmBlue[i, j]);
                    int a = validador((int)Math.Round(wmAlpha[i, j]));
                    //int a = (int)Math.Round(wmAlpha[i, j]);
                    Color auxColor = Color.FromArgb(a,r,g,b);
                    watermarkedImage.SetPixel(j, i, auxColor);
                }
            }

            //Return the watermarked image
            return watermarkedImage;
        }
        private static int validador(int c)
        {           
            c = Math.Max(0, c);
            c = Math.Min(255, c);
            return c;
        }

        public static double testWatermark(Bitmap image, string clave)
        {
            Bitmap watermarkedImage = new Bitmap(image.Width, image.Height);

            //Create auxiliary matrices
            double[,] wmRed = new double[image.Height, image.Width];
            double[,] wmGreen = new double[image.Height, image.Width];
            double[,] wmBlue = new double[image.Height, image.Width];
            double[,] wmAlpha = new double[image.Height, image.Width];

            //Load them with the source color info
            for (int i = 0; i < image.Height; i++)
            {
                for (int j = 0; j < image.Width; j++)
                {
                    Color auxColor = image.GetPixel(j, i);
                    wmRed[i, j] = auxColor.R;
                    wmGreen[i, j] = auxColor.G;
                    wmBlue[i, j] = auxColor.B;
                    wmAlpha[i, j] = auxColor.A;
                }
            }

            //Convert the key to a long type. (It's simple hasing) ahora se hace en watermark
        

            //Make the dct direct transform
            wmRed = DCT.directTransform(wmRed);
            wmGreen = DCT.directTransform(wmGreen);
            wmBlue = DCT.directTransform(wmBlue);
            wmAlpha = DCT.directTransform(wmAlpha);

            //Extract the watermark
            Watermarker wmMarker = new Watermarker(clave);

            int[] extractedWMRed = wmMarker.ExtractWatermark(wmRed);
            int[] extractedWMBlue = wmMarker.ExtractWatermark(wmBlue);
            int[] extractedWMGreen = wmMarker.ExtractWatermark(wmGreen);
            int[] extractedWMAlpha = wmMarker.ExtractWatermark(wmAlpha);

            //Test the extracted watermark with the Normalized Correlation
            double NC = 0;

            NC = wmMarker.calcularNC(extractedWMRed);
            NC = Math.Max(NC, wmMarker.calcularNC(extractedWMBlue));
            NC = Math.Max(NC, wmMarker.calcularNC(extractedWMGreen));
            NC = Math.Max(NC, wmMarker.calcularNC(extractedWMAlpha));

            //Return the watermarked image
            return NC;
        }


        public static void inserterAUX(Bitmap image, String clave)
        {
            Watermarker w = new Watermarker(clave);
            int zancada = image.Width / 2;
            int h = image.Height -1;
            for (int i = 0; i < w.k; i++)
            {
                int ind1 = zancada + (2 * i);
                int ind2 = zancada + (2 * i) + 1;
                Color aux1 = image.GetPixel(ind1, h);
                Color aux2 = image.GetPixel(ind2, h);
                if (w.w[i] == 1)
                {
                    if (aux1.R <= aux2.R)
                    {                        
                        Color c1 = Color.FromArgb(aux1.A, validador(aux2.R + 1), aux1.G, aux1.B);
                        Color c2 = Color.FromArgb(aux2.A, validador(aux1.R - 1), aux2.G, aux2.B);
                        image.SetPixel(ind1, h, c1);
                        image.SetPixel(ind2, h, c2);
                    }
                }
                else
                {
                    if (aux1.R >= aux2.R)
                    {
                        Color c1 = Color.FromArgb(aux1.A, validador(aux2.R - 1), aux1.G, aux1.B);
                        Color c2 = Color.FromArgb(aux2.A, validador(aux1.R + 1), aux2.G, aux2.B);
                        image.SetPixel(ind2, h, c2);
                        image.SetPixel(ind1, h, c1);
                    }

                }
            }
        }
}

}
